package com.anxin.registerManagement.service;

import cn.hutool.core.util.ObjectUtil;
import com.anxin.registerManagement.bean.dto.UpdatePassWordDto;
import com.anxin.registerManagement.bean.dto.UserDto;
import com.anxin.registerManagement.bean.jo.UserSearchJo;
import com.anxin.registerManagement.bean.persist.ClassRoom;
import com.anxin.registerManagement.bean.persist.Profession;
import com.anxin.registerManagement.bean.persist.User;
import com.anxin.registerManagement.exception.BusinessException;
import com.anxin.registerManagement.mapper.ClassRoomMapper;
import com.anxin.registerManagement.mapper.ProfessionMapper;
import com.anxin.registerManagement.mapper.UserMapper;
import com.anxin.registerManagement.util.CommonUtil;
import com.anxin.registerManagement.util.Const;
import com.anxin.registerManagement.util.EmailUtil;
import com.anxin.registerManagement.util.RedisUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.UUID;

@Service
public class UserService {

    private static final Logger logger = LoggerFactory.getLogger(UserService.class);

    @Autowired
    UserMapper userMapper;

    @Autowired
    ClassRoomMapper classRoomMapper;

    @Autowired
    ProfessionMapper professionMapper;

    @Autowired
    RedisUtil redisUtil;

    /**
     * 查询用户
     */
    public PageInfo<User> getUserList(UserSearchJo userSearchJo) {
        if (!ObjectUtil.isEmpty(userSearchJo.getPageNum()) && !ObjectUtil.isEmpty(userSearchJo.getPageSize())) {
            PageHelper.startPage(userSearchJo.getPageNum(), userSearchJo.getPageSize());
        }
        return new PageInfo<>(userMapper.getUserList(userSearchJo));
    }

    /**
     * 获取用户信息
     */
    public UserDto getUserInfo() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes()).getRequest();
        String jwt = request.getHeader(Const.jwtName);
        // TODO:这里通过jwt去解析id，然后获取用户全部信息
        logger.info("jwt：{}", jwt);
        User user = userMapper.selectById(1);
        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(user, userDto);
        // 这里设置班级名称
        ClassRoom classRoom = classRoomMapper.selectById(user.getClassRoomId());
        Profession profession = professionMapper.selectById(classRoom.getProfessionId());
        String classRoomTotalName = profession.getProfessionName() + classRoom.getClassYear().toString().substring(classRoom.getClassYear().toString().length() - 2) + classRoom.getClassCode();
        userDto.setClassRoomTotalName(classRoomTotalName);
        return userDto;
    }

    /**
     * 修改用户信息
     */
    public void updateUserInfo(User user) {
        // 这里使用wrapper进行修改
        // 这里只能修改手机号、邮箱、民族、政治面貌、生源地以及家庭地址
        LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(User::getId, user.getId())
                .set(User::getTelephone, user.getTelephone())
                .set(User::getEmail, user.getEmail())
                .set(User::getNationalityId, user.getNationalityId())
                .set(User::getPoliticalStatusId, user.getPoliticalStatusId())
                .set(User::getArea, user.getArea())
                .set(User::getHomeAddress, user.getHomeAddress())
                .set(User::getDateOfBirth, user.getDateOfBirth());
        userMapper.update(null, lambdaUpdateWrapper);
    }

    /**
     * 获取所有用户
     */
    public List<User> getAllUser() {
        return userMapper.selectList(null);
    }

    /**
     * 修改用户状态->是否禁用
     */
    public void updateIsDisabled(int id, boolean isDisabled) {
        LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(User::getId, id).set(User::getIsDisabled, isDisabled);
        userMapper.update(null, lambdaUpdateWrapper);
    }

    /**
     * 修改用户->是否开启默认禁用
     */
    public void updateIsDisabledMode(int id, boolean isDisabled) {
        LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(User::getId, id).set(User::getIsDisabledMode, isDisabled);
        userMapper.update(null, lambdaUpdateWrapper);
    }

    /**
     * 添加用户
     */
    public void addUser(User user) {
        // 这里密码默认身份证后6位
        user.setPassWord(user.getIdCard().substring(user.getIdCard().length() - 6));
        userMapper.insert(user);
    }

    /**
     * 发送验证码通过邮箱
     */
    public String sendVerifyCodeByEmail(String userName, String passWord) {
        // TODO:这里需要做的是，通过账号密码查询邮箱，然后发送邮件
        // TODO:这里需要做的是解密密码，然后生成uuid加入redis中
        User user = getUserByUserNamePassWord(userName, passWord);
        if (ObjectUtil.isEmpty(user)) {
            throw new BusinessException(Const.ERROR_USERNAME_PASSWORD);
        }
        String uuid = UUID.randomUUID().toString();
        String code = CommonUtil.verificationCode(6);
        // 设置验证码，5分钟过期
        redisUtil.set(uuid, code, 60 * 5);

        try {
            EmailUtil.sendEmail("yqc852594498@qq.com",
                    "mxvslbptwwombeii",
                    user.getEmail(),
                    "修改密码",
                    "验证码：" + code);
        } catch (Exception e) {
            logger.error("发送邮箱失败" + e);
            throw new BusinessException("发送邮箱失败");
        }
        // TODO:返回的是UUID
        return uuid;
    }

    /**
     * 校验账号密码
     */
    public void verifyUsernamePassword(String userName, String passWord) {
        User userByUserNamePassWord = getUserByUserNamePassWord(userName, passWord);
        if (ObjectUtils.isEmpty(userByUserNamePassWord)) {
            throw new BusinessException(Const.ERROR_USERNAME_PASSWORD);
        }
    }

    /**
     * 校验验证码
     */
    public void verifyCode(String uuid, String code) {
        String queryCode = (String) redisUtil.get(uuid);
        if (!code.equals(queryCode)) {
            throw new BusinessException(Const.ERROR_CODE);
        }
    }

    /**
     * 修改密码
     */
    public void updatePassword(UpdatePassWordDto updatePassWordDto) {
        // TODO:注意这里的password都是加密过后的

        // TODO:首先需要通过redis，查找uuid为key 的值，是否与code相同，再去修改
        // 通过redis获取验证码信息
        String getCode = (String) redisUtil.get(updatePassWordDto.getUuid());
        if (!updatePassWordDto.getCode().equals(getCode)) {
            throw new BusinessException(Const.ERROR_CODE);
        }
        if (ObjectUtils.isEmpty(getUserByUserNamePassWord(updatePassWordDto.getUserName(), updatePassWordDto.getPassWord()))) {
            throw new BusinessException(Const.ERROR_USERNAME_PASSWORD);
        }
        LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(User::getUserName, updatePassWordDto.getUserName())
                .eq(User::getPassWord, updatePassWordDto.getPassWord())
                .set(User::getPassWord, updatePassWordDto.getNewPassWord());
        userMapper.update(null, lambdaUpdateWrapper);
    }

    /**
     * 通过账号密码查询用户
     */
    public User getUserByUserNamePassWord(String userName, String passWord) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getUserName, userName).eq(User::getPassWord, passWord);
        return userMapper.selectOne(lambdaQueryWrapper);
    }

    /**
     * 修改用户信息——用户列表功能
     */
    public void updateUserInfoByUserList(User user) {
        LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(User::getId, user.getId())
                .set(User::getUserName, user.getUserName())
                .set(User::getNickName, user.getNickName())
                .set(User::getIdCard, user.getIdCard())
                .set(User::getSex, user.getSex())
                .set(User::getClassRoomId, user.getClassRoomId())
                .set(User::getAdmissionYear, user.getAdmissionYear())
                .set(User::getAcademicYear, user.getAcademicYear());
        userMapper.update(null, lambdaUpdateWrapper);
    }

    /**
     * 通过id获取用户信息
     */
    public User getUserById(int id) {
        User user = userMapper.selectById(id);
        // 这里密码不应该返回去
        user.setPassWord(null);
        return user;
    }

    /**
     * 通过用户名获取用户信息
     */
    public User getUserByUserName(String userName) {
        return userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUserName, userName));
    }
}
